Random number generators are the spice of many cryptographic algorithms. Stream ciphers rely on them heavily, and they have uses in many other relevant sectors. The problem that occurs is that most of them are really quite bad.
Most of the random number generators that are included with things like the c libraries are statistically random, but for a random number generator to actually be secure for cryptrographic purposes it must be impossible to calculate the next number it will spit out from one you just got. Here's the rub: these pseudorandom number generators generally do just what they musn't.
When I discovered that there was a severe lack of cryptographically secure pseudorandom number generators available to me, I lost several night's sleep thinking of ways to get an irreproduceable, non-algorithmic seqence of numbers. I was not a pretty sight afterwards. In my infinite benevolence, I'll tell you the ideas that came to me.
According to Bruce Schneier, the best source of randomness is the real world. Unfortunately, computers dont find the real world to be a readily accessable medium, so we must improvise.
The Wondrous Sound Card Based Idea
Cheap soundcards finally have a use! Their line noise is effectively random, and better yet, it is affected by the magnetic fields emitted by other components (who the fuck knows what they are doing at any given moment, and how the hell can you guess the strength of that effect?).
So here's our random number generator:
1) Unplug any microphones from your sound card. We want the background noise of a sound card, not the background noise of a geek's room.
2) Stop playing those MP3's for a minute, you won't die (use the CD player if you have a CD, it will not affect the results in any relevant fashion, see magnetic field note above).
3) Crank the line input and recording volumes. If your sound card is less than godly, you will be graced with a comfortably loud fuzz.
4) Capture some of that fuzz.
5) The level of the fuzz is probably somewhat constant, so the more significant bytes of your samples may not be too useful; they will probably even be periodic. The less significant bytes will be far more random, the least significant completely so. Now just make a decision: to have a bunch of completely random bytes, only use the lest significant bit of every sample. If you want or need to save space/computation time, use more (no more than 2 bits on an 8-bit sound card, probably no more than 3 on a 16-bit). Combining them would be something like this:
mov ebx, Sample shl ebx, 1Fh ;eliminates all but the least significant bit shr ebx, 1Eh ;sets the little bugger into the 2nd bit (leaving ;the 1st empty) mov ecx, n ;n is the length of the number minus one @anotherbit call GetASample ;this is some procedure to get a sample from the ;soundcard or from a file containing fuzz mov nextSample,eax ;<-- assuming that the sample is returned in eax mov edx, nextSample ; -. shl edx, 1Fh ; | shr edx, 1Fh ; | adds the least significant of another sample add ebx, edx ; | and moves all the bits up one spot. rol ebx, 1 ; -' loop @anotherbitThe result of this operation is a completely random number of length n+1 bits. It probably does not get much more random than this.
Of course, the whole process should be completely automated, and please remember to restore the recording volumes for tomorrow's karaoke party.
The Amazing Pseudorandom Sample
This idea is very similar to the previous one, except that it involves taking a sample from an audio stream at pseudorandom intervals. This would probably be using the CD input or digital extraction from a CD. Here, the faults of the pseudorandom sequence generator are minimized because it is only being used to point to data instead of being the data itself. Since music's waveform is notoriously periodic, you may get a roughly periodic sequence. This can be eliminated by combining the least significant bit[s] of many samples as in the previous example.
The Slightly Less Amazing Pseudorandom File Sample
This one is weaker than the others that have been done so far. As a natural extension of the second idea, I thought, "what if I were to use some file somewhere as the sample source?" The upside of this approach would be that none of the multimedia devices on the computer would need to be accessed. This can work well if implemented properly, but there are some additional complications.
First of all, remember that a CD track is a constant bombardment of sound samples, these being periodic measurements of a sound wave. It is all a bunch of bitwise chaos. On the other hand, most files on a hard drive have some more formal order and are thus ill suited to forming a random sample space. Text files are almost exclusively alphanumeric characters and punctuation in a predictable order, and even executables have a degree or repetitiveness, since certain patterns appear with high frequency. Much better are zip and mp3 files, since their bulk is compressed data which has very little repetition; still, they have headers/footers which are far more predictable.
The most significant weakness of this method is that long streams will probably force you to return to the beginning of the file and start over, this adds an unwanted period to your stream source. This weakness is present in the preceding method, but since an entire CD is almost invariably huge compared to a single file it is far more negligable. Because of this potential weakness, combining the least significant bits of pseudorandomly chosen bytes/words/whatever will probably be an absolute necessity.
These ideas should create some reasonably random sequences. Hopefully, they are at least adequately random so that any weaknesses will not provide enough of an edge for an attacker to target them instead of another part of your cryptosystem.